package com.blctek.cryptoserver.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: 吴青珂
 * @Date: 2021/03/28/0:08
 * @Description:
 */
public class SecretUtils {

    /**
     * 密钥
     */
    private static final String KEY ="1234123412341234";//十六位的十六进制密钥

    /**
     * 算法
     */
    private static final String ALGORITHM = "AES";

    /**
     * 算法/模式/补码方式
     */
    private static final String MODE = "AES/ECB/PKCS5Padding";

    /**
     * 字符集
     */
    private static final String CHARSET = StandardCharsets.UTF_8.name();

    /*static {
        Security.addProvider(new BouncyCastleProvider());
    }*/

    /**
     * 十六进制字符串转为字节数组
     * @param hexStr
     * @return
     */
    private static byte[] hexStringToByteArray(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length()/2];
        for (int i = 0;i< hexStr.length()/2; i++) {
            int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
            int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    /**
     * 字节数组转为十六进制字符串
     * @param byteArr
     * @return
     */
    private static String byteArrayToHexString(byte[] byteArr) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < byteArr.length; i++) {
            int v = byteArr[i] & 0xff;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append("0");
            }
            sb.append(hv);
        }
        return sb.toString();
    }

    /**
     * 加密：利用key（密钥）和aes算法的模式（mode）生产cipher，再利用doFinal加密
     * 此时返回的是字节数组，再将其转为十六进制字符串
     * @param word
     * @return
     */
    public static String encrypt(final String word) {
        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(CHARSET), ALGORITHM);
            Cipher cipher = Cipher.getInstance(MODE); // "算法/模式/补码方式"
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            return byteArrayToHexString(cipher.doFinal(word.getBytes(CHARSET)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密：利用key（密钥）和aes算法的模式（mode）生产cipher，再利用doFinal解密
     * 此时需要将十六进制转为字节数组才能解密
     * @param word
     * @return
     */
    public static String decrypt(final String word) {
        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(CHARSET), ALGORITHM);
            Cipher cipher = Cipher.getInstance(MODE); // "算法/模式/补码方式"
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            return new String(cipher.doFinal(hexStringToByteArray(word)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String origin = "testtest";
        String encrypt = encrypt(origin);
        String decrypt = decrypt(encrypt);
        System.out.println("key->"+KEY);
        System.out.println("origin->"+origin);
        System.out.println("encrypt->"+encrypt);
        System.out.println("decrypt->"+decrypt);
        System.out.println("6b7ded86cde60ec6ef475095d1577008".equals(encrypt));
    }
}
